<?php
/**
 * Created by PhpStorm.
 * User: Krystal
 * Date: 2019/1/10
 * Time: 13:24
 */

namespace app\common\model;

use think\Cache;

/**
 * 鉴爱词条
 * Class AuthenticateLoveText
 * @package app\common\model
 */
class AuthenticateLoveText extends Base
{
    protected $table = 'wechat_backup_07_18_14_43_00.app_authenticate_love_text';

    /**
     * 缓存key
     * key 后面连上 词条id
     */
    const CACHE_KEY = 'authenticate_text_';

    /**
     * 缓存时间 7天
     * 86400为一天
     */
    const CACHE_TIME = 86400 * 7;

    /**
     * 获取一条鉴爱结果词条
     * @param array $map
     * @return array
     */
    public function getAuthenticateText($map = [])
    {
        $recode1 = $map['recode1'] ?? 0;
        $recode2 = $map['recode2'] ?? 0;
        $self_id = $map['self_id'] ?? 0;
        $is_save = $map['is_save'] ?? 0;

        $result = $this->resortAndFilterResult($map['result']);
        $tags = [];
        // 需要的从数据中获取的词条id数组
        $textIds = '';
        // 临时数组
        $temp = [];
        foreach ($result as $k => $d)
        {
            if ($this->cache_on > 1)
            {
                $temp[$d['id']] = Cache::get(self::CACHE_KEY . $d['id']);
            } else
            {
                $temp[$d['id']] = false;
            }
            /**
             * 词条内容未缓存，等待从数据库中获取
             * 拼接数据库查询 需要的 ids 字符串
             */
            if ($temp[$d['id']] === false)
            {
                // 先从临时数组中删除，避免数据库中查询失败造成问题
                unset($temp[$d['id']]);
                // 拼接ids字符串
                $textIds .= ',' . $d['id'];
            }
        }
        if ($textIds != '')
        {
            // 去掉开头的,
            $textIds = substr($textIds, 1);

            try
            {
                $data = $this
                    ->field('id,keywords,text,status')
                    ->where('id in(' . $textIds . ')')
                    ->selectOrFail();

                $data = json_decode(json_encode($data, true), true);
            }
            catch (\Exception $e)
            {
                $data = [];
            }
            // 数据库中查询成功，写入缓存并写入到前面的数组中
            if (!empty($data))
            {
                foreach ($data as $v)
                {
                    // 将鉴爱词条内容缓存
                    if ($this->cache_on >= 1)
                    {
                        Cache::set(self::CACHE_KEY . $v['id'], $v, self::CACHE_TIME);
                    }
                    // 将数据库查出来的内容 写入到数组中为空的部分
                    $temp[$v['id']] = $v;
                }
            }
        }
        if (!empty($temp))
        {
            $i = 1;
            foreach ($result as $k => $v)
            {
                $textTemp = $temp[$v['id']];
                // 去掉不显示的词条 并且只显示5个词条
                if ((int)($textTemp['status']) !== 1 || $i > 5)
                {
                    unset($result[$k]);
                    continue;
                }
                $result[$k]['title'] = $tags[] = $textTemp['keywords'];

                // 结果词条进行正则替换 , recode2 VS recode1 (右 VS 左)
                if ($recode1 && $recode2 && $self_id)
                {
                    $result[$k]['content'] = $this->replaceText($recode1, $recode2, $self_id, $textTemp['text'], $is_save);
                }
                $i++;
            }
        }
        // 默认为迷之缘分
        if (count($tags) == 0)
        {
            $result[0] = $this->useDefaultText();

            $result[0]['score'] = 100;
            $result[0]['title'] = $result[0]['keywords'];

            // 结果词条进行正则替换 , recode2 VS recode1 (右 VS 左)
            if ($recode1 && $recode2 && $self_id)
            {
                $result[0]['content'] = $this->replaceText($recode1, $recode2, $self_id, $result[0]['text'], $is_save);
            }

            $tags[0] = $result[0]['keywords'];

            unset($result[0]['keywords']);
        }

        $result = array_merge($result);

        $result = ['tags' => $tags, 'text' => $result];

        return $result;
    }

    protected function getText($id = 0)
    {
        $data = [];

        if ((int)($id) > 0)
        {
            $data = false;

            if ($this->cache_on > 1)
            {
                $data = Cache::get(self::CACHE_KEY . $id);
            }
            if ($data === false)
            {
                $field = 'id,status,keywords,text';
                try
                {
                    $data = $this->field($field)->where('id', $id)->findOrFail()->toArray();
                }
                catch (\Exception $e)
                {
                    $this->error = '鉴爱词条不存在';
                    $data = [
                        'id' => 22,
                        'status' => 1,
                        'keywords' => '迷之缘分',
                        'text' => 'TA与ni的关系有各种各样的可能，ta会以哪种方式喜欢你，是一个只能用现实去解开的迷。或许随着时间的进展，星座女神会揭示出更多的秘密，但请记住，只有亲自体会到的爱情才是真的爱情，生活，永远无法用星座代替。',
                    ];
                }
                if ($this->cache_on > 1)
                {
                    Cache::set(self::CACHE_KEY . $id, $data, self::CACHE_TIME);
                }
            }
        }
        return $data;
    }

    /**
     * 对鉴爱结果进行排序并过滤
     * @param string $result 未处理的鉴爱结果字符串
     * @return array
     *  id      鉴爱结果词条id
     *  score   鉴爱结果该词条获得的分数
     */
    protected function resortAndFilterResult($result = '')
    {
        $data = [];

        if ($result != '')
        {
            /**
             * 数据存储格式为【词条id-分数,词条id-分数,词条id-分数】
             * 此处先拆分 为数组
             */
            $temp = explode(',', $result);

            foreach ($temp as $k => $v)
            {
                $rec = explode('-', $v);
                // 词条id
                $textId = (int)($rec[0]);
                // A_VS_B 当前词条所得分数
                $score = (int)($rec[1]);

                $data[] = [
                    'id' => $textId,
                    'score' => $score
                ];
            }
            // 将结果按分数进行倒序排序
            $data = resort($data, 'score');

            // 获取前五的鉴爱结果
            $dataFirstFive = array_slice($data, 0, 5);

            $textIds = [];
            foreach ($dataFirstFive as $k => $d)
            {
                $textIds[] = $d['id'];
            }
            // 需要移除的词条id
            $shouleUnsetTextids = [];

            /**
             * 心之归宿37、灵魂伴侣7、心灵守护8 三者同时出现排在前5，将心灵守护在显示中移除
             * 天雷地火21、合欢铃29同时出现且排在前5，将天雷地火在显示中移除
             */
            $filter1 = [7, 8, 37];
            $filter2 = [21, 29];
            // 判断数组交集 是满足过滤条件
            if ($filter1 == array_intersect($filter1, $textIds))
            {
                $shouleUnsetTextids[] = 8;
            } elseif ($filter2 == array_intersect($filter2, $textIds))
            {
                $shouleUnsetTextids[] = 21;
            }

            foreach ($data as $k => $d)
            {
                if (in_array($d['id'], $shouleUnsetTextids))
                {
                    unset($data[$k]);
                } else
                {
                    // 使鉴爱分数不一致，若后面的分数=前面的分数 则前面的分数+1
                    if (($k + 1) < count($data) && $data[$k + 1]['score'] == $d['score'])
                    {
                        $d['score']++;
                    }
                    $data[$k]['score'] = $this->ModScore($d['score']);
                }
            }
        }
        return $data;
    }

    /**
     * 使鉴爱分数在 1～999 之间
     * @param int $score
     * @param int $min
     * @param int $max
     * @return int
     */
    protected function ModScore($score = 0, $min = 1, $max = 999)
    {
        $score = (int)($score);

        if ($score > $max)
        {
            $score = $max;
        } elseif ($score < $min)
        {
            $score = $min;
        }
        return $score;
    }

    /**
     * 获取默认为空的词条 即迷之缘分
     * @param int $id
     * @return array
     */
    protected function useDefaultText($id = 22)
    {
        $data = false;

        if ($this->cache_on > 1)
        {
            $data = Cache::get(self::CACHE_KEY . $id);
        }
        if ($data === false)
        {
            try
            {
                $data = $this->field('id,keywords,text,status')
                    ->where('id', $id)
                    ->findOrFail()->toArray();
            }
            catch (\Exception $e)
            {
                $data = [
                    'id' => 22,
                    'keywords' => '蜜汁缘分',
                    'text' => 'ta与你的关系有各种各样的可能，ta会以哪种方式喜欢你，是一个只能用现实去解开的迷。或许随着时间的进展，星座女神会揭示出更多的秘密，但请记住，只有亲自体会到的爱情才是真的爱情，生活，永远无法用星座代替。',
                    'status' => 1
                ];
            }
            if ($this->cache_on > 1)
            {
                Cache::set(self::CACHE_KEY . $id, $data, self::CACHE_TIME);
            }
        }

        return $data;
    }

    /**
     * 词条中的人称进行替换
     * @param array $recode1
     * @param array $recode2
     * @param int $selfid
     * @param string $text
     * @param int $is_save 是否为微信刚填写完信息的时候的查看
     * @return string
     */
    protected function replaceText($recode1 = [], $recode2 = [], $selfid = 0, $text = '', $is_save = 0)
    {
        if (empty($recode1) || empty($recode2) || $selfid == 0)
        {
            return $text;
        }
        $replaceLeft = '{{';
        $replaceRight = '}}';
        $replace1Origin = 'TA';
        $replace2Origin = 'ta';
        $replace3Origin = '你';
        $replace4Origin = 'ni';

        $replace1Text = $replaceLeft . $replace1Origin . $replaceRight;
        $replace2Text = $replaceLeft . $replace2Origin . $replaceRight;
        $replace3Text = $replaceLeft . $replace3Origin . $replaceRight;
        $replace4Text = $replaceLeft . $replace4Origin . $replaceRight;

        $text = str_replace($replace1Origin, $replace1Text, $text);
        $text = str_replace($replace2Origin, $replace2Text, $text);
        $text = str_replace($replace3Origin, $replace3Text, $text);
        $text = str_replace($replace4Origin, $replace4Text, $text);

        $replace1 = $replace1Origin;
        $replace2 = $replace2Origin;
        $replace3 = $replace3Origin;
        $replace4 = $replace4Origin;
        /**
         * 如果是“自己对某人”
         *  ta/TA替换为你
         *  ni替换为对方名字，你替换为他或她
         *
         * 若为H5刚填写完信息的查看，则
         *  TA 替换为自己名称
         *  ni替换为你
         *  ta替换为他或她
         */
        if ($recode2['id'] == $selfid)
        {
            if ($is_save)
            {
                $replace1 = $recode2['name'];
                $replace2 = $recode2['type'] == 1 ? '他' : '她';
                $replace3 = $replace4 = '你';
            } else
            {
                $replace1 = $replace2 = '你';
                $replace3 = $recode1['type'] == 1 ? '他' : '她';
                $replace4 = $recode1['name'];
            }
        } /**
         * 如果是“某人对自己”
         *  TA替换为对方名字
         *  ta替换为她或他
         *  ni换成你
         */
        elseif ($recode1['id'] == $selfid)
        {
            $replace1 = $recode2['name'];
            $replace2 = $recode2['type'] == 1 ? '他' : '她';
            $replace3 = $replace4 = '你';
        } /**
         * 如果是“某人甲VS某人乙” ta ni TA
         *  ta/TA替换为某人乙的名字
         *  你/ni替换为某人甲的名字
         */
        elseif (($recode1['id'] !== $selfid) && ($recode2['id'] !== $selfid))
        {
            $replace1 = $replace2 = $recode2['name'];
            $replace3 = $replace4 = $recode1['name'];
        }
        $text = str_replace($replace1Text, $replace1, $text);
        $text = str_replace($replace2Text, $replace2, $text);
        $text = str_replace($replace3Text, $replace3, $text);
        $text = str_replace($replace4Text, $replace4, $text);

        return $text;
    }
}
